package com.ss.project.xia17user.core.aspect;


import com.ss.project.xia17user.core.exceptions.BadRequestException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 全局异常捕捉
 * @author xia17
 * @date 2020/7/23 17:30
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    private static final String ERROR_VIEW_NAME = "error";


    /**
     * 处理所有不可知的异常
     */
    @ExceptionHandler(Throwable.class)
    public ModelAndView exception(Throwable e){
        log.error("系统未知异常",e);
        return buildMv("系统未知错误",e.getMessage());
    }

    /**
     * 处理异常
     * @param e /
     */
    @ExceptionHandler(OAuth2AuthenticationException.class)
    public String auth2AuthenticationException(OAuth2AuthenticationException e,HttpServletRequest request,HttpServletResponse response)  {
        log.error("Oauth认证异常",e);
        request.setAttribute("status",400);
        response.setStatus(400);
        ModelAndView view = buildMv("系统未知错误", e.getMessage());

        return "error";
    }

    /**
     * 错误请求
     */
    @ExceptionHandler(BadRequestException.class)
    public ModelAndView badRequestException(BadRequestException e){
        log.error("已知异常",e);
        return buildMv(e.getMessage(),e.getMessage());
    }


    /**
     * 构建错误
     * @param message 消息
     * @param details details
     * @return /
     */
    ModelAndView buildMv(String message , String details){
        return buildMv(HttpStatus.INTERNAL_SERVER_ERROR,message,details);
    }


    public static ModelAndView buildMv(HttpStatus status ,String message,String details){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setStatus(status);
        modelAndView.setViewName(ERROR_VIEW_NAME);
        modelAndView.addObject("message",message);
        modelAndView.addObject("status",status.value());
        modelAndView.addObject("error",status.getReasonPhrase());
        modelAndView.addObject("details",details);
        return modelAndView;
    }


}
